/*
 * loadscreen.cpp
 *
 *  Created on: 21/12/2008
 *      Author: smaxll
 */

#include "loadscreen.hpp"
#include "font.hpp"

#include <iostream>

#define MIN_PERCENTAGE 0
#define MAX_PERCENTAGE 100


loadscreen::loadscreen(SDL_Surface *screen, const int & percent):
    screen_(screen),
    logo_drawn(false),
    pby_offset_(0),
    prcnt(percent)
{
    logo_surface_ = IMG_Load("images/misc/logo.png");
    if (!logo_surface_) {
        std::cerr << "loadscreen: Failed to load the logo: " << "image/misc/logo.png" << std::endl;
    }

    // Initialize the text area which is to be used for showing the text about buttons.
    text_area.x = text_area.y = text_area.w = text_area.y = 0;

}


/**
 * Set the progress bar with the percentage provided. This function is used to generate dynamic progressing bar.
 */
void loadscreen::set_progress(const int percentage, const std::string &text, const bool commit){
    //! Saturate percentage.
    if(percentage < MIN_PERCENTAGE){
        prcnt = MIN_PERCENTAGE;
    }else if(percentage > MAX_PERCENTAGE){
        prcnt = MAX_PERCENTAGE;
    }else{
        prcnt = percentage;
    }

    // Set progress bar parameters:
    int fcr =  21, fcg =  53, fcb =  80;        // RGB-values for finished piece.
    int lcr =  21, lcg =  22, lcb =  24;        // Leftover piece.
    int bcr = 188, bcg = 176, bcb = 136;        // Border color.
    int bw = 1;                             //!< Border width.
    int bispw = 1;                              //!< Border inner spacing width.
    bw = 2*(bw+bispw) > screen_->w ? 0: 2*(bw+bispw) > screen_->h ? 0: bw;
    int scrx = screen_->w - 2*(bw+bispw);   //!< Available width.
    int scry = screen_->h - 2*(bw+bispw);   //!< Available height.
    int pbw = scrx/2;                           //!< Used width.
    int pbh = scry/16;                          //!< Used heigth.
//    surface const gdis = screen_.getSurface();
    SDL_Rect area;
    // Draw logo if it was succesfully loaded.
    if (logo_surface_ && !logo_drawn) {
        area.x = (screen_->w - logo_surface_->w) / 2;
        area.y = ((scry - logo_surface_->h) / 2) - pbh;
        area.w = logo_surface_->w;
        area.h = logo_surface_->h;
        // Check if we have enough pixels to display it.
        if (area.x > 0 && area.y > 0) {
            pby_offset_ = (pbh + area.h)/2;
            SDL_BlitSurface (logo_surface_, 0, screen_, &area);
        } else {
            std::cerr << "loadscreen: Logo image is too big." << std::endl;
        }
        logo_drawn = true;
        SDL_UpdateRect(screen_, area.x, area.y, area.w, area.h);
    }
    int pbx = (scrx - pbw)/2;                   // Horizontal location.
    int pby = (scry - pbh)/2 + pby_offset_;     // Vertical location.

    // Draw top border.
    area.x = pbx; area.y = pby;
    area.w = pbw + 2*(bw+bispw); area.h = bw;
    SDL_FillRect(screen_,&area,SDL_MapRGB(screen_->format,bcr,bcg,bcb));
    // Draw bottom border.
    area.x = pbx; area.y = pby + pbh + bw + 2*bispw;
    area.w = pbw + 2*(bw+bispw); area.h = bw;
    SDL_FillRect(screen_,&area,SDL_MapRGB(screen_->format,bcr,bcg,bcb));
    // Draw left border.
    area.x = pbx; area.y = pby + bw;
    area.w = bw; area.h = pbh + 2*bispw;
    SDL_FillRect(screen_,&area,SDL_MapRGB(screen_->format,bcr,bcg,bcb));
    // Draw right border.
    area.x = pbx + pbw + bw + 2*bispw; area.y = pby + bw;
    area.w = bw; area.h = pbh + 2*bispw;
    SDL_FillRect(screen_,&area,SDL_MapRGB(screen_->format,bcr,bcg,bcb));
    // Draw the finished bar area.
    area.x = pbx + bw + bispw; area.y = pby + bw + bispw;
    area.w = (prcnt * pbw) / (MAX_PERCENTAGE - MIN_PERCENTAGE); area.h = pbh;
    SDL_FillRect(screen_,&area,SDL_MapRGB(screen_->format,fcr,fcg,fcb));
    // Draw the leftover bar area.
    area.x = pbx + bw + bispw + (prcnt * pbw) / (MAX_PERCENTAGE - MIN_PERCENTAGE); area.y = pby + bw + bispw;
    area.w = ((MAX_PERCENTAGE - prcnt) * pbw) / (MAX_PERCENTAGE - MIN_PERCENTAGE); area.h = pbh;
    SDL_FillRect(screen_,&area,SDL_MapRGB(screen_->format,lcr,lcg,lcb));
    // Clear the last text and draw new if text is provided.
    if(text.length() > 0 && commit)
    {
        SDL_Rect oldarea = text_area;
        SDL_FillRect(screen_,&text_area,SDL_MapRGB(screen_->format,0,0,0));
        text_area = font::line_size(text, font::SIZE_NORMAL);
        text_area.x = scrx/2 + bw + bispw - text_area.w / 2;
        text_area.y = pby + pbh + 4*(bw + bispw);
//        text_area = font::draw_text(&screen_,text_area,font::SIZE_NORMAL,font::NORMAL_COLOUR,text,text_area.x,text_area.y);
//        oldarea.x = minimum<int>(text_area.x, oldarea.x);
//        oldarea.y = minimum<int>(text_area.y, oldarea.y);
//        oldarea.w = maximum<int>(text_area.w, oldarea.w);
//        oldarea.h = maximum<int>(text_area.h, oldarea.h);
        SDL_UpdateRect(screen_, oldarea.x, oldarea.y, oldarea.w, oldarea.h);
    }
    // Update the rectangle if needed
    if(commit)
    {
        SDL_UpdateRect(screen_, pbx, pby, pbw + 2*(bw + bispw), pbh + 2*(bw + bispw));
    }

}

/**
 * Increment the progress bar.
 */
void loadscreen::increment_progress(const int percentage, const std::string &text, const bool commit){
    set_progress(prcnt+percentage, text, commit);
}

/**
 * Make the screen black
 */
void loadscreen::clear_screen(const bool commit)
{
    int scrx = screen_->w;                  //!< Screen width.
    int scry = screen_->h;                  //!< Screen height.
    SDL_Rect area = {0, 0, scrx, scry};     // Screen area.


    // Make everything black.
    SDL_FillRect(screen_,&area,SDL_MapRGB(screen_->format,0,0,0));
    if(commit)
    {
        SDL_Flip(screen_);                     // Flip the double buffering.
    }
}

loadscreen* loadscreen::global_loadscreen = 0;
